Skip to main content
Glama
monostate

100ms Raydium Sniper MCP

by monostate
shyft-market.js5.48 kB
const { Connection, PublicKey } = require('@solana/web3.js'); const dotenv = require('dotenv'); const bs58 = require('bs58'); const WebSocket = require('ws'); const { Market } = require('@raydium-io/raydium-sdk'); const { startWebSockets, setMatchingPoolCallback, closeAllConnections: closeWsConnections } = require('./test-ws-raw.js'); const { getMarketAccounts } = require('./lib/market-decoder.js'); // Re-export closeAllConnections exports.closeAllConnections = closeWsConnections; dotenv.config(); // Constants exports.RAYDIUM_PROGRAM_ID = new PublicKey('675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8'); exports.RENT_EXEMPTION = 2039280; exports.SLIPPAGE_BPS = 100; // Constants const HELIUS_RPC = 'https://mainnet.helius-rpc.com/?api-key=471d92ec-a326-49b2-a911-9e4c20645554'; const SOLANA_RPC = 'https://api.mainnet-beta.solana.com'; // Market info cache const marketInfoCache = new Map(); const MARKET_CACHE_DURATION = 60000; // 60 seconds // Initialize Helius connection for market data const heliusConnection = new Connection(HELIUS_RPC, { commitment: 'processed', confirmTransactionInitialTimeout: 10000 }); // Single active search token mint let activeSearchTokenMint = null; let searchResolver = null; /** * Gets pool and market info for a token using WebSocket only. */ async function getPoolAndMarketInfo(tokenMint, connection) { return new Promise((resolve, reject) => { const timeout = setTimeout(() => { cleanup(); reject(new Error('POOL_NOT_FOUND')); }, 10 * 60 * 1000); // 10 minutes timeout const startTime = Date.now(); console.log(`[Pool Search] Starting search for ${tokenMint}`); // Start WebSocket connection startWebSockets(tokenMint); function cleanup() { clearTimeout(timeout); closeWsConnections(); // Always close connections in cleanup setMatchingPoolCallback(null); // Clear callback } // Set callback for pool discovery setMatchingPoolCallback(async (poolInfo) => { const poolFoundTime = Date.now(); console.log(`[Pool Found] Found pool in ${poolFoundTime - startTime}ms via WebSocket`); try { const serumStartTime = Date.now(); const serumInfo = await getSerumMarketInfo(poolInfo.marketId, poolInfo.marketProgramId, connection); console.log(`[Serum] Market info fetched in ${Date.now() - serumStartTime}ms`); const combined = combinePoolAndMarketInfo(poolInfo, serumInfo); if (combined) { // Don't cleanup here - let the transaction complete first resolve([combined, 'websocket']); } } catch (error) { console.error('[Error] Failed to get market info:', error.message); cleanup(); // Only cleanup on error reject(error); } }); }); } // Cache PublicKey instances const publicKeyCache = new Map(); function getCachedPublicKey(key) { if (!publicKeyCache.has(key)) { publicKeyCache.set(key, new PublicKey(key)); } return publicKeyCache.get(key); } async function getSerumMarketInfo(marketId, marketProgramId, connection) { try { const serumStartTime = Date.now(); // Use provided connection for market accounts const marketAccounts = await getMarketAccounts(connection, marketId, marketProgramId); if (!marketAccounts) { throw new Error('Failed to fetch market accounts'); } return { serumProgramId: getCachedPublicKey(marketProgramId), serumMarket: getCachedPublicKey(marketId), serumBids: getCachedPublicKey(marketAccounts.bids), serumAsks: getCachedPublicKey(marketAccounts.asks), serumEventQueue: getCachedPublicKey(marketAccounts.eventQueue), serumCoinVault: getCachedPublicKey(marketAccounts.baseVault), serumPcVault: getCachedPublicKey(marketAccounts.quoteVault), serumVaultSigner: getCachedPublicKey(marketAccounts.vaultSigner), serumTime: Date.now() - serumStartTime }; } catch (error) { throw error; } } // Cache static PublicKey const STATIC_AMM_AUTHORITY = new PublicKey('5Q544fKrFoe6tsEbD7S8EmxGTJYAKtTVhAW5Q5pge4j1'); function combinePoolAndMarketInfo(pool, serumInfo) { return { ammMarket: getCachedPublicKey(pool.pubkey), ammAuthority: STATIC_AMM_AUTHORITY, ammOpenOrders: getCachedPublicKey(pool.openOrders), ammTargetOrders: getCachedPublicKey(pool.targetOrders), poolCoinTokenAccount: getCachedPublicKey(pool.baseVault), poolPcTokenAccount: getCachedPublicKey(pool.quoteVault), ...serumInfo }; } /** * Derives the market authority using the given programId and marketId. */ function getAssociatedAuthority({ programId, marketId }) { const seeds = [marketId.toBuffer()]; let nonce = 0; while (nonce < 100) { try { const seedsWithNonce = seeds.concat(Buffer.from([nonce]), Buffer.alloc(7)); const publicKey = PublicKey.createProgramAddressSync(seedsWithNonce, programId); return { publicKey, nonce }; } catch { nonce++; } } return null; } // Function to manage active search state function setActiveSearch(tokenMint) { if (tokenMint) { activeSearchTokenMint = tokenMint.toLowerCase(); } else { activeSearchTokenMint = null; } } module.exports = { RAYDIUM_PROGRAM_ID: exports.RAYDIUM_PROGRAM_ID, RENT_EXEMPTION: exports.RENT_EXEMPTION, SLIPPAGE_BPS: exports.SLIPPAGE_BPS, getPoolAndMarketInfo, setActiveSearch, closeAllConnections: exports.closeAllConnections };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/monostate/100ms-SPL-Token-Sniper-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server